package modeloCarmenSanDiego;

import java.util.ArrayList;
import java.util.List;

import modeloCarmenSanDiego.edificios.Edificio;
import modeloCarmenSanDiego.persistencia.CargadorDeArchivos;
import modeloCarmenSanDiego.pistas.Pista;



public class Juego {
	
	private OrdenDeArresto ordenDeArresto = new OrdenDeArresto("No Hay Acusado");
	private Caso caso;
	private Reloj reloj;
	private List<Ciudad> ciudades = new ArrayList<Ciudad>();
	private List<ObjetoRobado> objetosQuePuedenSerRobados = new ArrayList<ObjetoRobado>();
	private Comisaria comisaria;
	private ObjetoRobado robado;
	private Policia policia;
	private CargadorDeArchivos cargadorDeArchivos = new CargadorDeArchivos("src/xml/Ciudades.xml", "src/xml/Sospechosos.xml", ""); 
	
	private static final String nombreArchivoCiudadesGuardadas = "src/xml/CiudadesGuardadas.xml";
	private static final String nombreArchivoSospechososGuardados = "src/xml/SospechososGuardados.xml";
	private static final String nombreArchivoCasoGuardado = "src/xml/CasoGuardado.xml";
	
	
	
	public Juego(){
		this.reloj = new Reloj();
		this.comisaria = new Comisaria(this.reloj, this);
		this.policia = new Policia(this.reloj);
		this.objetosQuePuedenSerRobados = cargadorDeArchivos.cargarCiudadesYObjetosRobados(reloj);
		this.ciudades = this.armarListaDeCiudadesDeObjetosRobados();
		cargadorDeArchivos.cargarSospechosos(comisaria);
	}
	
	public void crearCaso() {
		this.reloj.resetearReloj();
		this.caso = new Caso(this.reloj, this.policia, this.comisaria.getSospechosos(), this.ciudades, this.objetosQuePuedenSerRobados);
		this.robado = caso.getObjetoRobado();
		this.ciudades = this.caso.getCiudadesMapeadas();
	}
	
	public Caso getCaso(){
		return this.caso;
	}
	
	public Juego(OrdenDeArresto ordenDeArresto){
		this.ordenDeArresto = ordenDeArresto;
	}
	
	public Reloj getReloj(){
		return this.reloj;
	}
	
	public ObjetoRobado getObjetoRobado() {
		return this.robado;
	}
	
	public List<Ciudad> getCiudades() {
		return this.ciudades;
	}
	
	public Comisaria getComisaria(){
		return this.comisaria;
	}
	
	public void setOrdenDeArresto(OrdenDeArresto ordenDeArresto) {
		this.ordenDeArresto = ordenDeArresto;
	}
	
	public Policia getPolicia(){
		return this.policia;
	}
	
	public boolean cerrarCaso(Ladron ladron){
		if (ordenDeArresto == null){
			return false;
		}
		if (ladron.getPerfil().getNombre() == ordenDeArresto.getNombre()){
			policia.addArresto();
			return true;
		}
		return false;
	}
	
	//constructor para desserializar
	public Juego(String archivoCiudadesGuardado, String archivoSospechososGuardado, String archivoCasoGuardado){
		
		ciudades = new ArrayList<Ciudad>();
		objetosQuePuedenSerRobados = new ArrayList<ObjetoRobado>();
		
		CargadorDeArchivos cargadorDeArchivosLocal = new CargadorDeArchivos(nombreArchivoCiudadesGuardadas, nombreArchivoSospechososGuardados, nombreArchivoCasoGuardado);
		this.reloj = cargadorDeArchivosLocal.cargarReloj();
		
		this.comisaria = new Comisaria(this.reloj, this);
		objetosQuePuedenSerRobados = cargadorDeArchivosLocal.cargarCiudadesYObjetosRobados(reloj);
		ciudades = this.armarListaDeCiudadesDeObjetosRobados();
		cargadorDeArchivosLocal.cargarSospechosos(this.comisaria);
		
		this.policia = cargadorDeArchivosLocal.cargarPolicia(this.reloj); 
		this.robado = cargadorDeArchivosLocal.cargarObjetoRobado(this.policia, this.reloj, this.ciudades.get(0));
		this.ordenDeArresto = cargadorDeArchivosLocal.cargarOrdenDeArresto();
		
		Ladron ladron = new Ladron(this.comisaria.getSospechosos().get(0));
		agregarCiudad(this.policia);
		
		caso = new Caso(this.policia, ladron, this.robado, this.ciudades, this.reloj);
		ladron.robarObjeto(this.robado);
	}
	
	private void agregarCiudad(Policia policia) {
		String nombreCiudad = policia.getCiudadActual().getNombre();
		for (Ciudad ciudadActual : ciudades) {
			if ( ciudadActual.getNombre().equals(nombreCiudad))
				policia.setCiudadActual(ciudadActual);
		}
	}
	
	private List<Ciudad> armarListaDeCiudadesDeObjetosRobados() {
		List<Ciudad> listaDeCiudades = new ArrayList<Ciudad>();
		for(ObjetoRobado robadoActual : this.objetosQuePuedenSerRobados)
			listaDeCiudades.add(robadoActual.getCiudad());
		return listaDeCiudades;
	}

	public void guardarPartida(){
		this.caso.guardarCiudades(nombreArchivoCiudadesGuardadas);
		this.caso.guardarCaso(nombreArchivoCasoGuardado, this.ordenDeArresto);
		this.comisaria.guardarSospechosos(nombreArchivoSospechososGuardados);
		
	}

	public boolean hayOrdenDeArresto() {
		return (! this.ordenDeArresto.getNombre().equals("No Hay Acusado"));
	}

	public void mezclarDestinosPolicia() {
		this.policia.mezclarDestinosPolicia();
	}
	
	public boolean policiaEnUltimaCiudad() {
		Ciudad ciudad = this.getPolicia().getCiudadActual();
		Camino camino = this.getCaso().getLadron().getCamino();
		return (camino.tieneComoUltimaCiudad(ciudad));
	}
		
	public boolean seAscendioDeGrado() {
		int arrestos = policia.getCantidadDeArrestos(); 
		return (arrestos == 4 || arrestos == 9 || arrestos == 19);
	}

	
	
	public void entrarAlEdificioNDeLaCiudadActual(int numEdificio) {
		Ciudad ciudadActual = this.policia.getCiudadActual();
		Ladron ladron = this.caso.getLadron();
		Edificio edificio = ciudadActual.getEdificios().get(numEdificio);
		elLadronEstaba = edificio.estaElLadron();
  		if( elLadronEstaba ){	
			seAtrapoAlLadron = this.cerrarCaso(ladron);
			return;
		}
		Pista pista = edificio.pedirPista(ladron, ciudadActual, this.policia.getRango().getDificultadDePista());
		seHirioAlPoliciaAlEntrarAlEdificio = edificio.seHirioAlPolicia();
		tipoDeHeridaAlEntrarAlEdificio = edificio.getTipoDeHerida();
		stringDePista = pista.toString();
		seTerminoElTiempoAlEntrarAlEdificio = this.reloj.seTerminoElTiempo();
	}
	
	private boolean elLadronEstaba;
	public boolean elLadronEstabaEnElEdificio(){
		return this.elLadronEstaba;
	}
	private boolean seAtrapoAlLadron;
	public boolean seAtrapoAlLadronAlEntrarAlEdificio(){
		return this.seAtrapoAlLadron;
	}
	private boolean seHirioAlPoliciaAlEntrarAlEdificio;
	public boolean seHirioAlPoliciaAlEntrarAlEdificio(){
		return this.seHirioAlPoliciaAlEntrarAlEdificio;
	}
	private String tipoDeHeridaAlEntrarAlEdificio;
	public String tipoDeHeridaAlEntrarAlEdificio(){
		return this.tipoDeHeridaAlEntrarAlEdificio;
	}
	private String stringDePista;
	public String stringDePistaAlEntrarAlEdificio(){
		return this.stringDePista;
	}
	private boolean seTerminoElTiempoAlEntrarAlEdificio;
	public boolean seTerminoElTiempoAlEntrarAlEdificio(){
		return this.seTerminoElTiempoAlEntrarAlEdificio;
	}
	
}